package com.yonyou.crm.cum.customer.appctrl;

import java.lang.reflect.Method;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.yonyou.crm.bpub.list.entity.AppListVO;
import com.yonyou.crm.bpub.list.entity.AppListValueVO;
import com.yonyou.crm.common.base.AppBaseCtrl;
import com.yonyou.crm.common.exception.CrmBusinessException;
import com.yonyou.crm.common.exception.CrmMessageException;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.crm.common.rest.apputil.AppRequestUtil;
import com.yonyou.crm.common.rest.constant.AppCodeConstant;
import com.yonyou.crm.common.rest.util.RequestUtil;
import com.yonyou.crm.common.rest.util.ResponseUtil;
import com.yonyou.crm.common.sort.entity.AppSortPlanEnum;
import com.yonyou.crm.cum.customer.entity.CustomerVO;
import com.yonyou.crm.cum.customer.rmitf.ICustomerRmService;
import com.yonyou.crm.sys.modules.entity.MtObjTypeEnum;

@RestController
@RequestMapping(value = "/{version}/mcum/accounts")
public class AppCustomerCtrl extends AppBaseCtrl{
	
	@Autowired
	private ICustomerRmService service;
	
	private String[] itemkeyOfEnumList = {"level", "type", "state","industry", "cannelType", "source"};
	
	/**
	 * 列表
	 * @param version
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(method = RequestMethod.GET)
	public Object getList(@PathVariable("version") String version, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		JSONObject paramObject = RequestUtil.getParamObject(request);
		int page = paramObject.getInt("page");
		int pageSize = paramObject.getInt("pageSize");
		checkPageInfo(page, pageSize);
		Page<CustomerVO> pageInfo = new Page<CustomerVO>(page, pageSize);
		
		Map<String, Object> searchMap = new HashMap<String, Object>();
		getSearchKeyForList(paramObject, searchMap); //搜索关键字
		getFilterForList(paramObject, searchMap); //列表筛选
		getOptionForList(paramObject, searchMap); //列表数据分类
		getSortOrderForPage(paramObject, searchMap); //排序依据
		
		Page<CustomerVO> customerPage = service.getList(pageInfo, searchMap);
		List<CustomerVO> dataList = customerPage.getData();
		List<AppListVO> list = new ArrayList<AppListVO>();
		
		AppListVO listLayout = getAppListLayout(MtObjTypeEnum.CUSTOMER.getValue());
		
		if (dataList != null) {
			for (int i = 0; i<dataList.size(); i++) {
				CustomerVO customer = dataList.get(i);
				AppListVO listVO = tranVoToAppListVO(customer, listLayout);
				list.add(listVO);
			}
		}
		
		Map<String, Object> customerList = new HashMap<String,Object>();
		customerList.put("list", list);
		return ResponseUtil.getObject(customerList);
	}
	
	/**
	 * 将数据转化为App列表数据
	 * @param customer
	 * @param listLayout
	 * @return
	 */
	public AppListVO tranVoToAppListVO(CustomerVO vo, AppListVO listLayout) {
		AppListVO listVO = new AppListVO();
		listVO.setId(vo.getId());
		
		List<List<AppListValueVO>> valueList = new ArrayList<>();
		Class<?> className = vo.getClass();
		List<List<AppListValueVO>> valueLayout = listLayout.getValuelist();
		if ((valueLayout != null) && (valueLayout.size() > 0)) {
			for(List<AppListValueVO> line : valueLayout) {
				List<AppListValueVO> colList = new ArrayList<>();
				if ((line != null) && (line.size() > 0)) {
					for(AppListValueVO value : line) {
						String itemkey = value.getItemkey();
						Object data;
						Object datavalue = "";
						if ("".equals(itemkey)) {
							//nothing
						} else if ("followTime".equals(itemkey)) {
							datavalue = getDataRangeStr(vo);
						} else if ("address".equals(itemkey)) {
							datavalue = getAddressInfo(vo);
						} else if ("ownerUserId".equals(itemkey)) {
							if ((vo.getSalesVOs() != null) && (vo.getSalesVOs().size() > 0)) {
								String department = vo.getSalesVOs().get(0).getOwnerDeptName() ;
								String userName = vo.getSalesVOs().get(0).getOwnerUserName();
								datavalue = department + "->" + userName;
							}
						} else {
							try {
								//首字母大写
								char[] cs = itemkey.toCharArray();
								cs[0] = Character.toUpperCase(cs[0]);
								String funcName = String.valueOf(cs);
								//获取方法名称
								Method getObject = className.getMethod("get"+funcName);
								
								if (Arrays.asList(itemkeyOfEnumList).contains(itemkey)) {
									Method getObjectName = className.getMethod("get"+funcName+"Name");
									data = getObjectName.invoke(vo);
									datavalue = (data == null) ? "" : data.toString();
								} else {
									data = getObject.invoke(vo);
									datavalue = (data == null) ? "" : data.toString();
								}
							} catch (Exception e) {
								throw new CrmBusinessException("动态调用客户方法错误！", e);
							}
						}
						AppListValueVO listValue = new AppListValueVO();
						listValue.setItemkey(itemkey);
						listValue.setDisplayvalue(datavalue);
						colList.add(listValue);
					}
				}
				valueList.add(colList);
			}
		}

		listVO.setValuelist(valueList);
		return listVO;
	}
	
	
	/**
	 * 根据最近跟进时间计算跟进区间
	 * @param followTime
	 * @return
	 */
	public String getDataRangeStr(CustomerVO customer) {
		Date followTime = customer.getFollowTime();
		if (followTime == null || followTime.equals("")) {
			followTime = customer.getCreatedTime();
		}
		Date now = new Date();
		String followTimeStr = "0天";
		long timeRange = now.getTime() - followTime.getTime();
		if (timeRange != 0) {
			long days = timeRange/(1000 * 60 * 60 * 24);
			if (days == 0) {
				followTimeStr = "今天已拜访";
			} else {
				followTimeStr = days + "天前拜访";
			}
		}
		return followTimeStr;
	}
	
	/**
	 * 排序依据
	 * @param paramObject
	 * @param pageInfo
	 * @throws CrmMessageException
	 */
	private void getSortOrderForPage(JSONObject paramObject, Map<String, Object> searchMap) throws CrmMessageException {
		String sortStr = "";
		String orderStr = "";
		Map<String, String> sortInfo = new HashMap<>();
		getSortForList(paramObject, sortInfo);
		if ((sortInfo != null) && (sortInfo.size() > 0)) {
			orderStr = String.valueOf(sortInfo.get("order"));
			Integer sortNum = Integer.valueOf(String.valueOf(sortInfo.get("field")));
			if (sortNum == AppSortPlanEnum.NAME.getValue()) {
				searchMap.put("orderBy", "c.`name`" + " " + orderStr);
			} else if(sortNum == AppSortPlanEnum.OWNER.getValue()){
				searchMap.put("orderBy", "s.owner_user_id" + " " + orderStr);
			} else if(sortNum == AppSortPlanEnum.CREATETIME.getValue()){
				searchMap.put("orderBy", "c.created_time" + " " + orderStr);
			} else if(sortNum == AppSortPlanEnum.FOLLOWUPTIME.getValue()){
				searchMap.put("orderBy", "s.follow_time" + " " + orderStr);
			} else if (sortNum == AppSortPlanEnum.BUYPOTENTIAL.getValue()) {
				searchMap.put("orderBy", "c.buy_potential" + " " + orderStr);
			} else {
				sortStr = "c.id";
				orderStr = "desc";
			}
		}
	}
	
	/**
	 * 排序依据
	 * @param paramObject
	 * @param pageInfo
	 * @throws CrmMessageException
	 */
	private void getSortOrderForPage(JSONObject paramObject, Page<CustomerVO> pageInfo) throws CrmMessageException {
		String sortStr = "";
		String orderStr = "";
		Map<String, String> sortInfo = new HashMap<>();
		getSortForList(paramObject, sortInfo);
		if ((sortInfo != null) && (sortInfo.size() > 0)) {
			orderStr = String.valueOf(sortInfo.get("order"));
			Integer sortNum = Integer.valueOf(String.valueOf(sortInfo.get("field")));
			if (sortNum == AppSortPlanEnum.NAME.getValue()) {
				sortStr = "c.`name`";
			} else if(sortNum == AppSortPlanEnum.OWNER.getValue()){
				sortStr = "s.owner_user_id";
			} else if(sortNum == AppSortPlanEnum.CREATETIME.getValue()){
				sortStr = "c.created_time";
			} else if(sortNum == AppSortPlanEnum.FOLLOWUPTIME.getValue()){
				sortStr = "s.follow_time";
			} else if (sortNum == AppSortPlanEnum.BUYPOTENTIAL.getValue()) {
				sortStr = "c.buy_potential";
			} else {
				sortStr = "c.id";
				orderStr = "desc";
			}
		}
		pageInfo.setSort(sortStr);
		pageInfo.setOrder(orderStr);
	}
	
	/**
	 * 新增与编辑
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value="/{objid}", method = RequestMethod.POST)
	public Object save(@PathVariable("version") String version, @PathVariable("objid") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		JSONObject dataJsonObject = AppRequestUtil.getFormParamObject(request);
		JSONObject headerJson = dataJsonObject.getJSONObject("header");
		CustomerVO customer = AppRequestUtil.getVO(headerJson, CustomerVO.class);
		
		String errorMsg = insertValidator(customer);
		if (!errorMsg.equals("")) {
			throw new CrmMessageException(AppCodeConstant.ServerError, errorMsg);
		}
		
		if(dataJsonObject.containsKey("subBnsType")){
			customer.setBiztypeId(dataJsonObject.getLong("subBnsType"));
		}
		
		if (id.equals(0L)) {
			customer = service.insert(customer);
		} else {
			customer.setId(id);
			customer = service.update(customer);
		}
		
		if (customer.getId() == null) {
			throw new CrmMessageException(AppCodeConstant.ServerError, "获取自增主键失败，未保存成功");
		}
		return ResponseUtil.getObject();
	}
	
	/**
	 * 数据校验
	 * @param customer
	 * @return
	 */
	private String insertValidator(CustomerVO customer) {
		String Message = "";
		if (customer == null) {
			Message = "客户实体转换失败";
		}
		if (!StringUtils.isNotBlank(customer.getName())) {
			Message = "客户名称不能为空";
        }
		return Message;
	}
	
	/**
	 * 删除
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
	public Object delete(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) {
		service.delete(id);
		return ResponseUtil.getObject();
	}
	
	/**
	 * 更新启用状态
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}/state", method = RequestMethod.PUT)
	public Object updateState(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) {
		int enableState = (int)RequestUtil.getObject(request, "enableState");
		service.updateState(id, enableState);
		return ResponseUtil.getObject();
	}
	
	/**
	 * 关注
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException 
	 */
	@RequestMapping(value = "{id}/follow", method = RequestMethod.PUT)
	public Object followState(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		if (id == null) {
			throw new CrmMessageException(AppCodeConstant.ClientError, "客户id不能为空");
		}
		String followState = String.valueOf(RequestUtil.getObject(request, "followState"));
		if (followState.equals("Y")) {
			service.saveFollow(id);
		} else if (followState.equals("N")){
			service.deleteFollow(id);
		} else {
			throw new CrmMessageException(AppCodeConstant.ClientError, "非法客户关注标识");
		}
		
		return ResponseUtil.getObject();
	}
	
	/**
	 * 变更负责人
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value = "{id}/changeowner", method = RequestMethod.POST)
	public Object changeOwner(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException{
		if (id == null) {
			throw new CrmMessageException(AppCodeConstant.ClientError, "客户id不能为空");
		}
		JSONObject paramObject = RequestUtil.getParamObject(request);
		String preOwnerUserId = paramObject.getString("prepersonid");
		String newOwnerUserId = paramObject.getString("newpersonid");
		// relatechangeowner ：客户下相关对象同步变更负责人；商机：opportunity;联系人：contact  只变更客户时，这个参数回传一个空的数组
		JSONArray relatechangeowner = paramObject.getJSONArray("relatechangeowner");
		//TODO 对负责人做校验
		if (("".equals(preOwnerUserId) || "0".equals(preOwnerUserId)) && ("".equals(newOwnerUserId) || "0".equals(newOwnerUserId))) {
			throw new CrmMessageException(AppCodeConstant.ClientError, "客户负责人不能都为空");
		}
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("cumId", id);
		paramMap.put("preOwnerUserId", preOwnerUserId);
		paramMap.put("newOwnerUserId", newOwnerUserId);
		paramMap.put("relatechangeowner",relatechangeowner);
		service.changeOwner(paramMap);
		return ResponseUtil.getObject();
	}

}
